from flask import Blueprint, jsonify, request, current_app
from werkzeug.security import generate_password_hash, check_password_hash
import jwt
import uuid
import datetime
from functools import wraps

from src.models.user_models import db, User, UserWallet, UserVip, Order

auth_bp = Blueprint('auth', __name__)

# 生成JWT token
def generate_token(user_id):
    payload = {
        'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=24),
        'iat': datetime.datetime.utcnow(),
        'sub': user_id
    }
    return jwt.encode(
        payload,
        current_app.config.get('SECRET_KEY'),
        algorithm='HS256'
    )

# Token验证装饰器
def token_required(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        token = None
        if 'Authorization' in request.headers:
            auth_header = request.headers['Authorization']
            try:
                token = auth_header.split(" ")[1]
            except IndexError:
                return jsonify({
                    'code': 401,
                    'message': '无效的认证令牌',
                    'data': None,
                    'timestamp': datetime.datetime.now().timestamp()
                }), 401

        if not token:
            return jsonify({
                'code': 401,
                'message': '缺少认证令牌',
                'data': None,
                'timestamp': datetime.datetime.now().timestamp()
            }), 401

        try:
            payload = jwt.decode(token, current_app.config.get('SECRET_KEY'), algorithms=['HS256'])
            user_id = payload['sub']
            current_user = User.query.filter_by(id=user_id).first()
            if not current_user:
                return jsonify({
                    'code': 401,
                    'message': '用户不存在',
                    'data': None,
                    'timestamp': datetime.datetime.now().timestamp()
                }), 401
        except jwt.ExpiredSignatureError:
            return jsonify({
                'code': 401,
                'message': '认证令牌已过期',
                'data': None,
                'timestamp': datetime.datetime.now().timestamp()
            }), 401
        except jwt.InvalidTokenError:
            return jsonify({
                'code': 401,
                'message': '无效的认证令牌',
                'data': None,
                'timestamp': datetime.datetime.now().timestamp()
            }), 401

        return f(current_user, *args, **kwargs)
    return decorated

# 用户注册
@auth_bp.route('/register', methods=['POST'])
def register():
    data = request.json
    
    # 验证必要字段
    if not data or not data.get('phone') or not data.get('password') or not data.get('verify_code'):
        return jsonify({
            'code': 400,
            'message': '请提供手机号、密码和验证码',
            'data': None,
            'timestamp': datetime.datetime.now().timestamp()
        }), 400
    
    # 验证手机号是否已存在
    if User.query.filter_by(phone=data.get('phone')).first():
        return jsonify({
            'code': 400,
            'message': '该手机号已注册',
            'data': None,
            'timestamp': datetime.datetime.now().timestamp()
        }), 400
    
    # TODO: 验证码验证逻辑，此处简化处理
    if data.get('verify_code') != '123456':  # 假设验证码为123456
        return jsonify({
            'code': 400,
            'message': '验证码错误',
            'data': None,
            'timestamp': datetime.datetime.now().timestamp()
        }), 400
    
    # 创建新用户
    new_user = User(
        phone=data.get('phone'),
        password=generate_password_hash(data.get('password')),
        nickname=data.get('nickname', f"用户{data.get('phone')[-4:]}"),
        register_time=datetime.datetime.now(),
        create_time=datetime.datetime.now(),
        update_time=datetime.datetime.now()
    )
    
    try:
        db.session.add(new_user)
        db.session.commit()
        
        # 创建用户钱包
        user_wallet = UserWallet(
            user_id=new_user.id,
            balance=0.00,
            total_recharge=0.00,
            total_consume=0.00,
            status=1,
            create_time=datetime.datetime.now(),
            update_time=datetime.datetime.now()
        )
        db.session.add(user_wallet)
        db.session.commit()
        
        # 生成token
        token = generate_token(new_user.id)
        
        return jsonify({
            'code': 200,
            'message': '注册成功',
            'data': {
                'userId': new_user.id,
                'token': token
            },
            'timestamp': datetime.datetime.now().timestamp()
        }), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'code': 500,
            'message': f'注册失败: {str(e)}',
            'data': None,
            'timestamp': datetime.datetime.now().timestamp()
        }), 500

# 用户登录
@auth_bp.route('/login', methods=['POST'])
def login():
    data = request.json
    
    # 验证必要字段
    if not data or not data.get('phone') or not data.get('password'):
        return jsonify({
            'code': 400,
            'message': '请提供手机号和密码',
            'data': None,
            'timestamp': datetime.datetime.now().timestamp()
        }), 400
    
    # 查询用户
    user = User.query.filter_by(phone=data.get('phone')).first()
    if not user or not check_password_hash(user.password, data.get('password')):
        return jsonify({
            'code': 401,
            'message': '手机号或密码错误',
            'data': None,
            'timestamp': datetime.datetime.now().timestamp()
        }), 401
    
    # 检查用户状态
    if user.status == 0:
        return jsonify({
            'code': 403,
            'message': '账号已被禁用',
            'data': None,
            'timestamp': datetime.datetime.now().timestamp()
        }), 403
    
    # 更新最后登录时间
    user.last_login_time = datetime.datetime.now()
    db.session.commit()
    
    # 生成token
    token = generate_token(user.id)
    
    # 查询会员信息
    vip_info = UserVip.query.filter_by(user_id=user.id, status=1).first()
    vip_expire_time = None
    if vip_info and vip_info.expire_time > datetime.datetime.now():
        vip_expire_time = vip_info.expire_time.strftime('%Y-%m-%d %H:%M:%S')
    
    return jsonify({
        'code': 200,
        'message': '登录成功',
        'data': {
            'userId': user.id,
            'token': token,
            'nickname': user.nickname,
            'avatar': user.avatar,
            'vipExpireTime': vip_expire_time
        },
        'timestamp': datetime.datetime.now().timestamp()
    }), 200

# 获取用户信息
@auth_bp.route('/user-info', methods=['GET'])
@token_required
def get_user_info(current_user):
    # 查询会员信息
    vip_info = UserVip.query.filter_by(user_id=current_user.id, status=1).first()
    vip_expire_time = None
    is_vip = False
    if vip_info and vip_info.expire_time > datetime.datetime.now():
        vip_expire_time = vip_info.expire_time.strftime('%Y-%m-%d %H:%M:%S')
        is_vip = True
    
    # 查询钱包信息
    wallet_info = UserWallet.query.filter_by(user_id=current_user.id).first()
    balance = 0.00
    if wallet_info:
        balance = float(wallet_info.balance)
    
    return jsonify({
        'code': 200,
        'message': '获取成功',
        'data': {
            'userId': current_user.id,
            'phone': current_user.phone,
            'nickname': current_user.nickname,
            'avatar': current_user.avatar,
            'gender': current_user.gender,
            'birthYear': current_user.birth_year,
            'birthMonth': current_user.birth_month,
            'birthDay': current_user.birth_day,
            'birthHour': current_user.birth_hour,
            'registerTime': current_user.register_time.strftime('%Y-%m-%d %H:%M:%S'),
            'lastLoginTime': current_user.last_login_time.strftime('%Y-%m-%d %H:%M:%S') if current_user.last_login_time else None,
            'isVip': is_vip,
            'vipExpireTime': vip_expire_time,
            'balance': balance
        },
        'timestamp': datetime.datetime.now().timestamp()
    }), 200

# 修改用户信息
@auth_bp.route('/user-info', methods=['PUT'])
@token_required
def update_user_info(current_user):
    data = request.json
    
    if data.get('nickname'):
        current_user.nickname = data.get('nickname')
    if data.get('avatar'):
        current_user.avatar = data.get('avatar')
    if data.get('gender') is not None:
        current_user.gender = data.get('gender')
    if data.get('birthYear'):
        current_user.birth_year = data.get('birthYear')
    if data.get('birthMonth'):
        current_user.birth_month = data.get('birthMonth')
    if data.get('birthDay'):
        current_user.birth_day = data.get('birthDay')
    if data.get('birthHour'):
        current_user.birth_hour = data.get('birthHour')
    
    current_user.update_time = datetime.datetime.now()
    
    try:
        db.session.commit()
        return jsonify({
            'code': 200,
            'message': '更新成功',
            'data': None,
            'timestamp': datetime.datetime.now().timestamp()
        }), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'code': 500,
            'message': f'更新失败: {str(e)}',
            'data': None,
            'timestamp': datetime.datetime.now().timestamp()
        }), 500

# 修改密码
@auth_bp.route('/change-password', methods=['PUT'])
@token_required
def change_password(current_user):
    data = request.json
    
    # 验证必要字段
    if not data or not data.get('oldPassword') or not data.get('newPassword'):
        return jsonify({
            'code': 400,
            'message': '请提供旧密码和新密码',
            'data': None,
            'timestamp': datetime.datetime.now().timestamp()
        }), 400
    
    # 验证旧密码
    if not check_password_hash(current_user.password, data.get('oldPassword')):
        return jsonify({
            'code': 401,
            'message': '旧密码错误',
            'data': None,
            'timestamp': datetime.datetime.now().timestamp()
        }), 401
    
    # 更新密码
    current_user.password = generate_password_hash(data.get('newPassword'))
    current_user.update_time = datetime.datetime.now()
    
    try:
        db.session.commit()
        return jsonify({
            'code': 200,
            'message': '密码修改成功',
            'data': None,
            'timestamp': datetime.datetime.now().timestamp()
        }), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'code': 500,
            'message': f'密码修改失败: {str(e)}',
            'data': None,
            'timestamp': datetime.datetime.now().timestamp()
        }), 500
